home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-06-23 | 26.1 KB | 470 lines | [TEXT/pdos] |
- Rez 101
- by: Tim Swihart
-
-
- So, you've heard how great resources are and how much easier they can
- make software development. You're eager to find out what resources can do
- for you, then suddenly, it hits you - you're not even sure what resources
- ARE!
-
- Even the best sample source code fails if the reader doesn't understand the
- concepts BEHIND that source. Why were certain tool calls used? How did the
- author decide which calls to use (there are roughly a thousand tool calls to
- choose from)? Why did the author use certain resource types and not
- others? Where do you go to learn more about all of this?
-
-
- Step Right Up!
-
- I'll tackle answering those questions and others like them in this file and in
- others to follow. Along the way, I'll point out other sources of more detailed
- information (to help you learn faster), I'll mention trade offs between doing
- things one way or doing them another, I'll cover various development tools
- that help make resources easier, and I'll try to do it all at a level that just
- about anyone can understand.
-
- In GEnie's A2Pro library and in America Online's ADV library are a series of
- source code samples that I wrote showing how to use resources in IIGS
- applications. This file is intended to explain Part 1 of the APW C-based Rez
- tutorial that I've uploaded to those libraries (if you don't have those files
- handy, then you should get them, it'll make this file more valuable). Later
- files will detail Part 2, Part 2.5, Part 3, etc of the resource tutorial files. That
- way, you have one detailed explanation for each part of the sample source.
-
- Future versions of this detailed explanation will ONLY explain the things that
- are NEW to whatever part they're supposed to "match". That means that the
- detailed explanation for Part 2 won't contain this background information
- and it won't talk about starting up the tools (Part 1 will do that). You should
- be prepared to read each of the files in this series in order to understand all
- of what's involved in using resources in your own applications.
-
-
- The Problem:
-
- All Apple IIGS programs that use the Toolbox need to use certain data
- structures like menu bars, window templates, icons, strings, etc. The original
- way to handle these within an application was to hard code it inside the
- source files to the applications themselves. If you wanted to rename a
- menu, change the title of a window, make a window bigger or smaller, etc,
- then you had to edit your source, compile it, link it, run it, and repeat until
- you achieved the desired affect.
-
- What if you wanted to do a French version of your application? You had to
- go back into your source code to try it all out, you had to once again use trial
- and error to get your controls to line up (their sizes would change no doubt if
- the text within them changed to a new language).
-
- This "edit/compile/link/run/repeat" method was usually VERY time
- consuming. Linking large applications can be very time consuming,
- recompiling source code over and over is also very time consuming, but
- there just weren't any other ways to do it.
-
- Changing the user interface to your applications was a nightmare. Many
- developers just didn't bother to fix "holes" in their user interface because
- they were tired of recompiling just for minor tweaks.
-
- What if there was a special place you could store the templates for all of
- these structures? What if there was a special place you could put all of the
- text strings that your applications use? What if there was a faster way to
- create things like windows, menus, etc? What if it were possible to make
- sweeping changes to the user interfaces within seconds - without "breaking"
- your application?
-
- What if we defined a special part of the file to contain nothing more than the
- collection of these structures and their contents? How would your
- application be able to tell one structure from another? How would you
- access these structures? How would you create them?
-
-
- Enter Resources:
-
- Since the introduction of Apple IIGS System Disk v.5.0.2, there IS a special
- place for keeping all of these "things" that need to be tweaked, converted to
- foreign languages, embellished, etc. This special place is known as the
- "resource fork" of a file.
-
- Each structure within your application COULD (they don't HAVE to) now be
- placed in another portion of your application (the resource fork). The
- Resource Manager takes care of keeping track of where within the file your
- structure lives and loads it into memory for you when you need it. Each of
- these individual structures living in the resource fork are called "resources".
- So, the simple definition of a resource is data that is needed for your
- application.
-
- Individual resources are kept track of by the Resource Manager because
- EVERY resource has a specific "type" and a specific "ID" (you assign the ID,
- what you're trying to use the resource for defines the type). Apple defined
- the most commonly used types and published the definitions for those types
- in Apple IIGS Toolbox Reference Manual, Volume 3 (available as I type this
- in beta form from APDA and soon to be available in "final" form from
- Addison-Wesley at better bookstores and [of course] at APDA).
-
- For the sake of those of you who don't have Toolbox Reference Volume 3, I'll
- BRIEFLY describe each type of resource when ever it gets added to the
- resource tutorial application. I will not go into tons of detail (Volume 3 is
- over a thousand pages and I'm not going to paraphrase that much!). If you
- need more information or explanation that I've provided, then you should
- either post a specific question either in A2Pro or ADV or get Volume 3 and
- read what Apple says (it's a great book to have <hint, hint>).
-
-
- How Do Resources Get Used?
-
- If you need a specific resource in memory, you can tell the Resource
- Manager to load it by making the tool call "LoadResource". It's fairly rare
- that you have to use LoadResource yourself!!! Why? Because most of the
- standard resource types are loaded for you when you make specific calls to
- OTHER tool sets (such as the Window Manager or the Menu Manager)! The
- resource sample source code (up through Part 3.2) does NOT use
- LoadResource - it's simply not needed.
-
- System Disk 5.0 introduced a number of new tool calls to several toolbox
- Managers so that these Manager could support resources. You create a
- window the old way by calling "NewWindow". You create a window using
- resources by calling "NewWindow2" (notice the "2" on the end of the call).
- Using the old way, you would add menus to your application by calling
- NewMenuBar and then adding the menus one by one by calling InsertMenu
- on each of them (ugh! sounds like a lot of work). Using resources, you can
- install a menu bar, its menus, and all of the items within those menus with
- ONE call - NewMenuBar2. (ahhh, much easier!)
-
- So, the answer to "How do I use resources?" is simply create the resources
- your application will need and let the toolbox use them for you. You simply
- pass references to the resources to the toolbox and the computer takes it
- from there.
-
-
- What's A Reference?:
-
- Before we go any further, let's look at a new data type that we need to
- understand. The new tool calls can your resources for the information they
- need or they can use structures that you already have in memory (or that
- you hard coded within your application). These calls can accept either a
- handle to the data structure you want to use, a pointer to the data structure,
- or the ID of the resource you want to use. This handle/point/resource ID is
- referred to as a "reference". In other words, a reference is the way that the
- toolbox gets to the actual data structure.
-
- How does the toolbox know whether you've passed a pointer, a handle, or a
- resource ID? Simple, YOU tell the toolbox what you're passing, every time
- you pass it! Each tool call that accepts a reference also REQUIRES that you
- tell it what kind of reference you've passed!
-
- The bits that describe the type of reference passed is called a "reference
- descriptor" or simply a "refDesc". Toolbox Volume 3 has more details and
- explains the bit patterns used for the different types of reference
- descriptors. Since I'm trying to teach you about resources, all of the
- resource-related tool calls I've used have resource ID's as their reference.
-
-
- Tools to Help:
-
- There are several ways to create resources. The first tool that was available
- to developers is a "resource compiler" from Apple named "Rez". Rez takes
- text descriptions of resources and converts them into actual resources (which
- is why it's called a "compiler"). Since Rez takes text files as input, it's very
- easy to upload resources TODAY to share with others - you simply upload
- the text description and the downloaders compile it to create the actual
- resources (this gets around the problem of current file packer's not being
- able to cope with FILES that have resources). You can also put the resources
- themselves on a disk and pack the disk for uploading, but when sending
- sample source code, the text version is often faster (because you only pack
- the files, not the whole disk). Also, the text-based descriptions of resources
- help newer developers unravel the structure of resources.
-
- Creating things like windows filled with controls by typing in text
- descriptions is often cumbersome. That's where desktop applications like
- SSSi's "GeneSys" comes in handy. GeneSys (and competing programs not yet
- released) let you "draw" your window, menus, controls, etc on the desktop
- (so you can see what they look like immediately) and GeneSys creates either
- the Rez source for you or creates the resources directly.
-
- Rez can do things no other tool can do yet - such as combining several
- resource forks into one, easily supporting custom resources types, reading
- data files and saving them as resources (so you can move sampled sounds,
- pictures, etc into resources easily). So, Rez should be in every developer's
- arsenal of tools!
-
- The package of tools that Rez comes in includes a resource decompiler (called
- DeRez). DeRez allows you to convert existing resources back into text
- descriptions. If you use a different tool to create your resources directly,
- then you can convert those resources to text using DeRez. Why would you
- want to do this? Several reasons, this protects you from anything that
- trashes your resource fork (if your resources get trampled, simply use Rez to
- recompile them - this is called "Rez-urrecting your resource fork"). You can
- also do this as an easier way to "archive" your application's source code.
-
- Many tasks require a more visually oriented tools (such as GeneSys) to get
- the job done quickly. So having BOTH Rez and a desktop tool like GeneSys
- should be seriously considered! If you decide to not have both, then
- consider again. It's that important.
-
- The resource tutorials that I've uploaded, and the descriptions like this file
- all assume that you have Rez. If you don't have Rez then you can get it by
- calling either Developer Tools Express or APDA (if you don't belong to APDA,
- then call Developer Tools Express). Both APDA and Developer Tools Express
- use the same phone number (1-800-282-2732 from U.S., 1-800-637-0029
- from Canada, and 408-562-3910 from International). Tell them you want to
- order part number A0240LL/A (price is fifty dollars). This package includes
- a collection of tools for use with the APW and ORCA shells that are used
- throughout this tutorial series.
-
-
- Every App Has To...:
-
- Every Apple IIGS application that wants to use the Toolbox has to start up
- the individual tool sets that the application expects to use. The application
- also has to start up any tool sets that are needed by the tool set the app
- wants to use (you many not care about the Memory Manager, bu you can bet
- the other tools do!). These tools have to be started up in just the right order
- - that order is listed in a tech note, several books, etc, so it is fairly easy to
- find this out. Some of the tool sets need some memory in bank zero (called
- direct page space) and the starting points of each tool's direct page space has
- to be passed to the tools as they are started up. Before you can pass this
- direct page space, you have to request it.
-
- Starting up tools in this way is an ugly process, you have to know the right
- order to start things up in, you have to request direct page space from the
- Memory Manager, and you have to pass this space to the tools as you start
- them up one by one. It would sure be a LOT easier if we could just make a
- list of what tools we want started up and have the computer figure out how
- much direct page space was needed, get the direct page space for us and
- start the tools for us as well. That would let us make ONE tool call to start
- ALL of the tools our application needs!
-
- Well, System Disk 5.0 introduced just such a tool call. It's called
- "StartUpTools" (naturally) and it makes life a LOT easier for us! Now, to start
- all of the tools your application will need, simply make a list (the format for
- this list is given in Toolbox Reference, Volume 3), and pass your user ID
- (which you get from the Memory Manager), a reference descriptor (so
- StartUpTools knows whether it's getting a pointer, a handle, or a resource
- ID), a reference to this list. We're showing how to use resources so the
- reference descriptor we use is "refIsResource" (this is a constant defined in
- the interfaces files by Apple). The reference we pass is the resource ID of
- the tools list (which lives in the resource fork).
-
-
- What's in the tools list?:
-
- Earlier in this file, I told you that the type of the resources you use is
- dictated by what you want to do with that resource. In order to use a tool
- list in a resource to start all of the tools, it has to be of type "rToolStartup".
- This name (rToolStartup) is a constant defined in the Types.Rez interface file.
- In order to create a resource of this type, we create a text file (see the
- "rTutor.Rez" file) that contains a line telling Rez to include (i.e.: read in) the
- standard resource types file (called "Types.Rez") and then we can describe
- the actual resource itself using the syntax that Rez expects to see.
-
- Comments in Rez source files can be in either of two formats. If you see a
- pair of slashes (i.e.: //) then that means the rest of that line is treated by
- Rez as a comment and ignored. If you see a slash followed immediately by
- an asterisk (i.e.: /*), then that starts a comment - to end that comment, Rez
- has to see an asterisk followed by a slash (i.e.: */). This second form can be
- as long as you want it and can span multiple lines. I'll use either type in my
- Rez source throughout the tutorial, so be sure you remember both of them.
-
- If we strip all of the comments out of the rTutor.Rez file, we're left with the
- "#include Types.Rez" line (which we already discusses) and a funny looking
- structure that starts with "resource rToolStartup (1)". This funny looking
- structure is how we tell Rez what we want in the various parts of the tool
- startup list.
-
- The word "resource" at the beginning of the line simply tells Rez that we're
- starting the description of a resource and that we'll use a template (from
- Types.Rez this time, but we can also define our own if we'd rather) to
- describe the parts of this resource. It's possible to create resources by just
- passing Rez a bunch of bytes of data - those types of resources start off with
- "data" instead of "resource".
-
- The next thing on the line we're talking about is "rToolStartup" - this is the
- TYPE of the resource we're about to describe. Remember, the type is
- dictated by what you want to do with it - we want to start up the tools so we
- HAVE to use the type of "rToolStartup". The "(1)" is the resource ID we've
- assigned to this tool startup list. Since all resources are described by BOTH a
- type AND an ID, you can have multiple resources of the same TYPE (because
- they'll all have different ID's) and of the same ID (as long as their types are
- different).
-
- Why did I give this resource an ID of 1? Why not use 4129? Or some other
- number? I like to keep tutorial source simple, so I tend to number resources
- starting from 1 (which I use for the first resource of that type). I use a
- different numbering system for menus because you have to keep track of
- menu bars, menus, menu items, and the text strings that all of them use.
- The best way to do all of this is to define your own constants and use the
- constants between the parenthesis! i.e.: instead of using "1", I should have
- put "#define firstStartupList 1" in my Rez source ABOVE the "resource
- rToolStartup..." line. Then, I could have changed the "resource
- rToolStartup..." line to be: "resource rToolStartup (firstStartupList)" Since
- applications tend to have only one startup tools list, this isn't that big of a
- deal, but later on (when we get into menus) you'll see that this technique is
- almost mandatory in order to figure out what's going on.
-
- The curly brace ("{") tells Rez that we're starting the description of the
- rToolStartup list. The "$C080" that's on the next line is a hex number that
- Rez uses in the first field of the tool startup list. This field tells the toolbox
- whether your app wants to come up in 320 or 640 mode and allows you to
- set other QuickDraw attributes (if you want to know them all, see Toolbox
- Ref, Volume 3).
-
- A comma separates items within the test that describes the resource. We
- could cram everything onto one long line and Rez could figure it out. I like
- to be able to read what I've done (so I can catch errors), so I've manually
- formatted the listing.
-
- Let's think for a minute - how many tools are we going to start up? Will it
- always be the same number for EVERY application? How do we tell the
- toolbox that we only want to start up 17 of the tools (there are many more
- than just 17)? Obviously, we have to tell the toolbox how many items are in
- our list of tools. That can easily lead to errors if we have to count the
- number of tools our selves and put that number in a list. Adding a tool and
- forgetting to change the number could cause weird problems.
-
- Fortunately, Rez is smart enough to be able to count for us! So, instead of
- having to count the number of tools we want to start, we let Rez do it. (this
- requires some special fields in the template, if you want to know how it's
- done, see the Rez chapter of the APW Tools manual). Since the template
- takes care of whatever it is that's needed to make this auto-counting happen,
- we only have to open another layer of curly braces and list all of the tools.
- So, the next line of the Rez source is simply another curly brace ("{") and
- then comes the list of tools.
-
- Notice that each line has TWO numbers on it (separated by commas). The
- first number is the tool set's number (assigned by Apple) and the second
- number is the minimum version of that toolset that our application is willing
- to accept. "4, $0302" means that we must be able to start at least version 3.2
- of tool set #4 (QuickDraw). The "$" tells us the numbers after it are hex, the
- lack of any special characters in front of the "4" tell us that it's just a plain
- old decimal number. For details on how version number are decoded, look in
- the Toolbox Reference Manual (Volume 2 I believe).
-
- Why is the version number important???? As the IIGS's tools have become
- more mature over the years, new calls have been added. If you start up an
- old version of the tools, the calls you make may NOT have been implemented
- yet! That means your application will fail in some weird place! If you check
- the version numbers at startup, you'll know THEN whether or not all of the
- tool calls your application uses are implemented! Early versions of the Rez
- tutorial allows many of the version numbers to be MUCH lower than they
- should be (i.e.: it uses version 1.0 for things that should be 2.0 or higher).
- This will be fixed in whatever comes AFTER Part 3.2 (3.2 is already released,
- so there's no way to fix it until the next version is released).
-
- In your applications, be sure you check the version numbers!!!!
-
- After we've listed all of the tools the tutorial app needs started, we have to
- close the list with a curly brace ("}"). This marks the spot for Rez to stop
- counting (now Rez can fill in the count field for us). A second curly brace
- ("}") is needed to close the complete resource description (remember, we had
- two opening braces, so we HAVE to have two closing braces. A semicolon is
- added after the last closing brace to tell Rez the resource has been
- completely described.
-
-
- That's It for The Resource Fork:
-
- Part 1 of the Rez tutorial only includes ONE resource (the list used to start up
- the tools). Later part of this tutorial will add additional resources (and will
- NOT describe the rToolStartup resource).
-
- Since the resource fork of Part 1 has now been fully described, it's time to
- look at what's needed from within the application itself in order to use the
- rToolStartup resource we just created.
-
-
- The Application Itself:
-
- At this stage of the game, the application is only supposed to start up the
- tools, indicate that it succeeded and shut the tools back down. I made the
- application beep three times to indicate success. If the startup fails, you get
- no beeps. Either way, the tools are shutdown and the application quits back
- to the launching program. Your only indications of success are the brief view
- of the desktop and the three beeps. Don't be surprised if the brief view of
- the desktop does NOT have any menus showing - those don't get added until
- Part 2.
-
- There are two routines in the APW C source code file that make up Part 1 of
- the Rez tutorial application. All applications built with C need a routine
- named "main". The other routine is named "do_init_rom" and that's where
- we actually call StartUpTools. Since "do_init_rom" is called from within
- "main", we have to put "main" AFTER "do_init_rom", otherwise, the compiler
- will complain that it doesn't know what to do with the call to "do_init_rom"
- because the compiler has NOT yet seen a definition for "do_init_rom". So, if
- you're not a C fan, but you're studying this source anyways to learn about
- resources, you should now be able to tell what the different routines are for.
-
- "main" has about five lines of meaningful code (I'm ignoring comments and
- braces). The first one is simply a call to our routine that starts up the tools.
- I put the call to StartUpTools in a separate routine simply to make "main"
- easier to read. The second line tests the value of a boolean variable to
- determine whether or not the tools were successfully started up.
-
- If the startup was successful, then we make three calls to SysBeep (SysBeep
- is a toolbox routine that simply beeps once each time it's called). After the
- beeps, we shut down the tools by calling "ShutDownTools". If the startup
- failed, then we skip the three calls to SysBeep and immediately shut down
- the tools.
-
- ShutDownTools is a toolbox routine and is fully documented in IIGS Toolbox
- Reference Volume 3. This tool requires two parameters. The first one is a
- reference descriptor (which I explained earlier). The second parameter is
- the reference to the "StartStopRecord" that StartUpTools returned to us when
- we called it. The contents of a StartStopRecord are beyond the scope of this
- explanation (you can survive just fine for now without knowing what they
- are).
-
- Notice that the reference descriptor indicates the the reference we're passing
- to ShutDownTools is a HANDLE. I said earlier that we'd only be dealing with
- reference descriptors that are resources. Well, I was wrong. <grin> Since
- the StartStopRecord is initialized by calling StartUpTools and is only used
- again by ShutDownTools, I made it a regular variable.
-
- If you examine the contents of the "do_init_rom" routine, you'll see that it
- contains about six lines (ignoring comments and braces) of meaningful code.
- The first line gets our user ID from the Memory Manager. Under APW C, this
- is actually done for use by the code in the "start.root" file that we have to
- link with, so we can grab the "built in" variable's value and use it here.
- Users of ORCA/C may have to change "_ownerid" to what ever ORCA/C uses
- or replace it with a call to MMStartup (Memory Manager Startup routine).
-
- What? Start the Memory Manager again? Won't that fry it if we start it and
- it's already started? Turns out that MMStartup doesn't actually start the
- Memory Manager, it simply returns the user ID of whatever called it. So,
- we're safe calling MMStartup as often as we want to.
-
- The next line of code is the call to StartUpTools and it requires the three
- parameters I described much earlier. StartUpTools returns a reference to
- the StartStopRecord we talked about a little bit ago. This reference is a
- handle and is need for the ShutDownTools calls right before we quit this
- application.
-
- After we've called StartUpTools, we need to check for errors. Was our tool
- list correct? Did we pass all the right parameters to the call? (remember,
- the resource ID we pass is a LONG, don't forget to pass ALL of that LONG,
- passing only a WORD will cause StartUpTools to fail!). If the call worked, we
- set the boolean "gPunt" to FALSE. If there was an error returned by
- StartUpTools, then we set "gPunt" to TRUE.
-
- "gPunt" is a global (that's why it starts with "g" - that's a naming convention
- I use) variable that we'll use in various places within the application later
- on. Once we've added an event loop (Part 2.5), we'll use gPunt to determine
- when it's time to quit the application.
-
-
- Th-th-th-that's All Folks!
-
- I've described in pretty intricate detail how Part 1 of the Rez tutorial works.
- I've described what a resource is and given examples of how to use and
- define them. I've also talked about a couple of tools that are used to create
- resources. More details on Rez and on GeneSys can be found on both GEnie's
- A2Pro and on America Online (Rez is under ADV and GeneSys is in the SSSi
- section).
-
- If you have further questions, send me email (try the others first), post in
- the appropriate topic/folder, or read the manuals. Details on the Resource
- Manager and all of the new 5.0 tool calls that support resources are
- documented in Apple IIGS Toolbox Reference, Volume 3. Rez is documented
- in the manual that comes with "APW Tools & Interfaces". Enjoy!
-
-
- Tim S.
-
-